package com.backup.common.utils.excel;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.metadata.CellExtra;
import com.alibaba.excel.metadata.data.ReadCellData;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Data
@Slf4j
public class AnalysisEventListener extends com.alibaba.excel.event.AnalysisEventListener<Map<Integer,String>> {

    /**
     * 每隔5条存储数据库，实际使用中可以3000条，然后清理list ，方便内存回收
     */
    private static final int BATCH_COUNT = 1;
    List<Object> list = new ArrayList<>();

    private SheetData sheetData = new SheetData();

    @Override
    public void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) {
        super.invokeHead(headMap, context);

        List<String> header = new ArrayList<>();
        log.info(header.size() + "");

        for(Integer key : headMap.keySet()){
            ReadCellData cellData = headMap.get(key);
            String value = cellData.getStringValue();
            if(StringUtils.isEmpty(value)){
                if(header.size() < 1){
                    if(sheetData.getHeader().size() < 1){
                        value = "none-header";
                    }else{
                        value = sheetData.getHeader().get(sheetData.getHeader().size() - 1).get(0);
                    }
                }else{
                    value = header.get(header.size() - 1);
                }
            }
            header.add(value);
        }
        sheetData.getHeader().add(header);
    }

    @Override
    public void invoke(Map<Integer, String> dataMap, AnalysisContext analysisContext) {
        checkLen();
        List<String> line = new ArrayList<>();
        for(Integer key : dataMap.keySet()){
            String value = dataMap.get(key);
//            if(StringUtils.isEmpty(value)){
//                if(line.size() < 1){
//                    value = "none-data";
//                }else{
//                    value = line.get(line.size() - 1);
//                }
//            }
            if(StringUtils.isEmpty(value)){
                if(line.size() < 1){
                    if(sheetData.getDatas().size() < 1){
                        value = "none-header";
                    }else{
                        value = sheetData.getDatas().get(sheetData.getDatas().size() - 1).get(0);
                    }
                }else{
                    value = line.get(line.size() - 1);
                }
            }
            line.add(value);
        }
        sheetData.getDatas().add(line);
    }

    private void checkLen(){
        log.error("----------------------------" + list.size());

//        log.info("解析到一条数据:{}", JSON.toJSONString(data));
        // 达到BATCH_COUNT了，需要去存储一次数据库，防止数据几万条数据在内存，容易OOM
        if (list.size() >= BATCH_COUNT) {
            log.error("----------------------------" + list.size());
            // 存储完成清理 list
            list.clear();
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
    }

    /**
     * 处理合并单元格
     * @param data               解析数据
     * @param extraMergeInfoList 合并单元格信息
     * @return 填充好的解析数据
     */
    private void explainMergeData(Map<Integer,Map<Integer, String>> data, List<CellExtra> extraMergeInfoList) {
        //循环所有合并单元格信息
        extraMergeInfoList.forEach(cellExtra -> {
            int firstRowIndex = cellExtra.getFirstRowIndex();
            int lastRowIndex = cellExtra.getLastRowIndex();
            int firstColumnIndex = cellExtra.getFirstColumnIndex();
            int lastColumnIndex = cellExtra.getLastColumnIndex();

            Map<Integer,String> rdata = data.get(cellExtra.getRowIndex()) ;
            String val = null ;
            if(rdata != null){
                val = rdata.get(cellExtra.getColumnIndex()) ;
            }
            //遍历每行
            Map<Integer, String> rowData = null ;
            for(int i = firstRowIndex; i <= lastRowIndex; i++){
                rowData = data.get(i) ;
                if(rowData == null){
                    continue;
                }
                for(int c = firstColumnIndex; c <= lastColumnIndex; c++){
                    rowData.put(c,val) ;
                }
            }
        });
    }
}
